From: kaf24@firebug.cl.cam.ac.uk Date: Sun, 21 May 2006 19:15:58 +0000 (+0100) Subject: [LOADER] More sanity checks when parsing Elf images to avoid X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16047^2~10 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=ed7041aaffef1593f5654f4096fb86430f03c1ff;p=xen.git [LOADER] More sanity checks when parsing Elf images to avoid out-of-bounds array accesses when loading the image. Signed-off-by: Keir Fraser --- diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c index 1cb821b8b9..0c60f683cd 100644 --- a/tools/libxc/xc_load_elf.c +++ b/tools/libxc/xc_load_elf.c @@ -158,12 +158,17 @@ static int parseelfimage(const char *image, elf_pa_off_defined = (p != NULL); elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base; + if ( elf_pa_off_defined && !virt_base_defined ) + goto bad_image; + for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; vaddr = phdr->p_paddr - elf_pa_off + virt_base; + if ( (vaddr + phdr->p_memsz) < vaddr ) + goto bad_image; if ( vaddr < kernstart ) kernstart = vaddr; if ( (vaddr + phdr->p_memsz) > kernend ) @@ -184,11 +189,9 @@ static int parseelfimage(const char *image, if ( (kernstart > kernend) || (dsi->v_kernentry < kernstart) || - (dsi->v_kernentry > kernend) ) - { - ERROR("Malformed ELF image."); - return -EINVAL; - } + (dsi->v_kernentry > kernend) || + (dsi->v_start > kernstart) ) + goto bad_image; if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) dsi->load_symtab = 1; @@ -200,6 +203,10 @@ static int parseelfimage(const char *image, loadelfsymtab(image, 0, 0, NULL, dsi); return 0; + + bad_image: + ERROR("Malformed ELF image."); + return -EINVAL; } static int diff --git a/xen/common/elf.c b/xen/common/elf.c index 6fad5c5437..b5a18f317a 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -94,12 +94,17 @@ int parseelfimage(struct domain_setup_info *dsi) elf_pa_off_defined = (p != NULL); elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base; + if ( elf_pa_off_defined && !virt_base_defined ) + goto bad_image; + for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; vaddr = phdr->p_paddr - elf_pa_off + virt_base; + if ( (vaddr + phdr->p_memsz) < vaddr ) + goto bad_image; if ( vaddr < kernstart ) kernstart = vaddr; if ( (vaddr + phdr->p_memsz) > kernend ) @@ -120,11 +125,9 @@ int parseelfimage(struct domain_setup_info *dsi) if ( (kernstart > kernend) || (dsi->v_kernentry < kernstart) || - (dsi->v_kernentry > kernend) ) - { - printk("Malformed ELF image.\n"); - return -EINVAL; - } + (dsi->v_kernentry > kernend) || + (dsi->v_start > kernstart) ) + goto bad_image; if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) dsi->load_symtab = 1; @@ -136,6 +139,10 @@ int parseelfimage(struct domain_setup_info *dsi) loadelfsymtab(dsi, 0); return 0; + + bad_image: + printk("Malformed ELF image.\n"); + return -EINVAL; } int loadelfimage(struct domain_setup_info *dsi)